package com.ibeetl.dao;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;

import com.ibeetl.dao.common.DaoResult;
import com.ibeetl.dao.common.TestServiceInterface;

@SpringBootApplication
public class BeanchmarkApplication {
	
	static String projectRoot =  System.getProperty("user.dir") + File.separator ;

    @Autowired
    TestServiceInterface testService;

    @Value("${test.warmCount}")
    private int warmCount;
    @Value("${test.count}")
    private int testCount;

    @Value("${test.target}")
    private String target;


    private Map<String, Long> map = new HashMap<String, Long>();

    public static void main(String[] args) {
    	if(args.length!=0) {
    		SpringApplication.run(BeanchmarkApplication.class, args);
    	}else {
    		List<String> target = Arrays.asList(args).subList(1, args.length-1);
    		
    		if(args[0].equals("excel")) {
    			
    		}else if(args[0].equals("png")){
    			GenPng png = new GenPng();
        		png.make();
    		}
    		
    	}
        

    }
    
    private List<DaoResult> getDaoResult(List<String> targets){
    	 String root = projectRoot+ "result";
    	 List<DaoResult>  list = new ArrayList<>();
    	 for(String target:targets) {
    		 DaoResult result = new DaoResult();
    		 result.setDaoName(target);
    		 Properties ps = new Properties();
    		 try {
				ps.load(new FileReader(new File(root,target+".txt")));
				for(Entry<Object,Object> entry:ps.entrySet()) {
					result.getRet().put((String)entry.getKey(), Integer.valueOf((String)entry.getValue()));
				}
				list.add(result);
			} catch (Exception e) {
				throw new RuntimeException(e);
			} 
    	 }
    	 return list;
    }
    
    

    @Bean
    public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
        return args -> {
            test(warmCount, false);
            test(testCount, true);
            logFile(target);
           
        };
    }

    public void test(int time, boolean log) {
        testAdd(time, log);
        testUnique(time, log);
        testUpdateById(time, log);
        testPageQuery(time, log);
        testExample(time, log);
        testOrmQuery(time, log);
       

    }

    public void logFile(String target) throws IOException {
        String root = projectRoot+ "result";
        new File(root).mkdirs();
        File file = new File(root, target + ".txt");
        Properties ps = new Properties();
        for (Entry<String, Long> entry : map.entrySet()) {
            ps.put(entry.getKey(), String.valueOf(getTPS(entry.getValue())));
        }
        ps.store(new FileWriter(file), target + ",total=" + testCount+" tps:");
        System.out.println(ps);
    }
    
    private long getTPS(Long misc) {
        if(misc==0) {
            //有些测试部支持，返回0
            return 0;
        }
        return 1000*testCount/misc;
    }

    public void testAdd(int time, boolean log) {
        if (log) {
            start("testAdd");
        }
        for (int i = 0; i < time; i++) {
            testService.testAdd();
        }
        if (log) {
            end("testAdd");
        }
    }

    public void testUnique(int time, boolean log) {
        if (log) {
            start("testUnique");
        }
        for (int i = 0; i < time; i++) {
            testService.testUnique();
        }
        if (log) {
            end("testUnique");
        }
    }

    public void testUpdateById(int time, boolean log) {
        if (log) {
            start("testUpdateById");
        }
        for (int i = 0; i < time; i++) {
            testService.testUpdateById();
        }
        if (log) {
            end("testUpdateById");
        }
    }

    public void testPageQuery(int time, boolean log) {
        if (log) {
            start("testPageQuery");
        }
        for (int i = 0; i < time; i++) {
            testService.testPageQuery();
        }
        if (log) {
            end("testPageQuery");
        }
    }

    public void testExample(int time, boolean log) {
        if (log) {
            start("testExample");
        }
        for (int i = 0; i < time; i++) {
            testService.testExampleQuery();
        }
        if (log) {
            end("testExample");
        }
    }

    public void testOrmQuery(int time, boolean log) {
        if (log) {
            start("testOrmQuery");
        }
        for (int i = 0; i < time; i++) {
            testService.testOrmQUery();
        }
        if (log) {
            end("testOrmQuery");
        }
    }
    
    public void start(String key) {
        map.put(key, System.currentTimeMillis());
    }

    public void end(String key) {
        Long start = map.get(key);
        Long end = System.currentTimeMillis();
        map.put(key, end - start);
    }

}
